package com.technology.javase;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

//泛型  约束集合元素的类型，进行安全检查，把错误显示在编译期
//泛型  编译时类型检查 代码通用性更强
public class Generics {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //泛型方式
        Integer[] scores = new Integer[]{100, 98, 80};
        String[] names = new String[]{"语文", "数学", "英语"};
        Double[] moneys = new Double[]{10.1, 20.2, 30.3};

        Generics.print(scores);
        Generics.print(names);
        Generics.print(moneys);


        //类型擦除
        /**
         * 泛型只是在编译期间生存，编译后就被干掉了，真正运行时，大多情况下取而代之的是Object。
         * 下面的代码利用了jdk提供的强大的反射功能
         * */
        List<Integer> list = new ArrayList<>();

        //1. 编译器按泛型检查，类型报错。这是在编译阶段
        //list.add("chenzs");

        //2.但在时间运行时，泛型的地方就被替代为通用类型object
        Class<?> aClass = list.getClass();
        Method m =  aClass.getDeclaredMethod("add",Object.class);

        //3.利用发射得到的对象是运行时对象，其就可以设置非整形的数据
        m.invoke(list,"zhenzs");
        System.out.println(list.get(0));
    }

    //泛型方式

    /**
     * l  E - Element (在集合中使用，因为集合中存放的是元素)
     * l  T - Type（Java 类）
     * l  K - Key（键）
     * l  V - Value（值）
     * l  N - Number（数值类型）
     * l  ? - 表示不确定的java类型
     */
    public static <E> void print(E[] arr) {
        for (E e : arr) {
            System.out.println(e);
        }
    }

}
